package com.gsafety.wellsfort.service.knowledge;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gsafety.wellsfort.common.context.LoginContextUtil;
import com.gsafety.wellsfort.common.enums.CustomerTypeEnum;
import com.gsafety.wellsfort.common.enums.QuestionTypeEnum;
import com.gsafety.wellsfort.common.util.ApiResponse;
import com.gsafety.wellsfort.common.util.ResultCode;
import com.gsafety.wellsfort.dao.course.WorkPublishDAO;
import com.gsafety.wellsfort.dao.course.WorkPublishRangeDAO;
import com.gsafety.wellsfort.dao.knowledge.QuestionDAO;
import com.gsafety.wellsfort.dao.knowledge.WorkDAO;
import com.gsafety.wellsfort.dao.knowledge.WorkQuestionDAO;
import com.gsafety.wellsfort.dao.security.AdminDAO;
import com.gsafety.wellsfort.domain.dto.work.*;
import com.gsafety.wellsfort.domain.model.course.Course;
import com.gsafety.wellsfort.domain.model.course.CourseRange;
import com.gsafety.wellsfort.domain.model.course.WorkPublish;
import com.gsafety.wellsfort.domain.model.course.WorkPublishRange;
import com.gsafety.wellsfort.domain.model.knowledge.Question;
import com.gsafety.wellsfort.domain.model.knowledge.Work;
import com.gsafety.wellsfort.domain.model.knowledge.WorkQuestion;
import com.gsafety.wellsfort.domain.model.organization.Student;
import com.gsafety.wellsfort.domain.model.security.Admin;
import com.gsafety.wellsfort.domain.vo.IndexQueryVO;
import com.gsafety.wellsfort.domain.vo.IndexWorkVO;
import com.gsafety.wellsfort.domain.vo.QuestionVO;
import com.gsafety.wellsfort.domain.vo.WorkVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class WorkService {
    @Autowired(required = false)
    WorkDAO workDAO;
    @Autowired(required = false)
    WorkQuestionDAO workQuestionDAO;
    @Autowired(required = false)
    QuestionDAO questionDAO;
    @Autowired(required = false)
    AdminDAO adminDAO;
    @Autowired(required = false)
    private WorkPublishRangeDAO workPublishRangeDAO;
    @Autowired(required = false)
    WorkPublishDAO workPublishDAO;

    public Integer finishWorkCount() {
        return workDAO.finishWorkCount();
    }

    public ApiResponse<WorkBaseInfoDTO> saveBaseInfo(WorkBaseInfoDTO workBaseInfoDTO) {
        ApiResponse<WorkBaseInfoDTO> apiResponse = null;
        Work w = new Work();
        BeanUtils.copyProperties(workBaseInfoDTO, w);
        Admin admin=LoginContextUtil.getAdmin();
        w.setUpdateTime(new Date());
        if(admin!=null)w.setModified(admin.getId());
        w.setCurrentTotalScore(BigDecimal.ZERO);
        if (workBaseInfoDTO.getId() != null) {
            w.setUpdateTime(new Date());
            if(admin!=null)w.setModified(admin.getId());
            workDAO.updateByPrimaryKeySelective(w);
        } else {
            w.setPublicTimes(0);
            w.setCreateTime(new Date());
            w.setCreator(LoginContextUtil.getAdmin().getId());
            workDAO.insertSelective(w);
        }
        workBaseInfoDTO.setId(w.getId());
        apiResponse = ApiResponse.success(workBaseInfoDTO);
        return apiResponse;
    }

    public ApiResponse<WorkSettingDTO> saveWorkSetting(WorkSettingDTO workSettingDTO) {
        ApiResponse apiResponse = null;
        Work w = new Work();
        w.setId(workSettingDTO.getWorkId());
        w.setPassingScore(workSettingDTO.getPassingScore());
        if(workSettingDTO.getCurrentTotalScore().intValue()==0){
            return ApiResponse.error(ResultCode.ERROR.getCode(),"总分为0,不能提交！");
        }
        w.setCurrentTotalScore(workSettingDTO.getCurrentTotalScore());
        if (w.getId() != null) {
            w.setUpdateTime(new Date());
            w.setModified(LoginContextUtil.getAdmin().getId());
            workDAO.updateByPrimaryKeySelective(w);
        }
        try {
            if (workSettingDTO.getWorkQuestionSettingList().size() > 0) {
                List<WorkQuSettingDTO> workQuestionSettingList = workSettingDTO.getWorkQuestionSettingList();
                for (WorkQuSettingDTO workQuInfo : workQuestionSettingList) {
                    //修改题目作业信息;
                    Integer workQuRelId = workQuInfo.getWorkQuestionRelId();
                    WorkQuestion workQu = workQuestionDAO.selectByPrimaryKey(workQuRelId);
                    workQu.setScore(workQuInfo.getScore());
                    workQu.setSerialNum(workQuInfo.getSerialNum());
                    workQuestionDAO.updateByPrimaryKeySelective(workQu);
                    //同步一下题目得分和序号;
                    Integer qId = workQu.getQuestionId();
                    Question q = questionDAO.selectByPrimaryKey(qId);
                    q.setSerialNum(workQuInfo.getSerialNum() != null ? workQuInfo.getSerialNum() : 0);
                    q.setScore(workQuInfo.getScore());
                    questionDAO.updateByPrimaryKeySelective(q);
                }
            }
            apiResponse = ApiResponse.success(workSettingDTO);
        } catch (Exception e) {
            e.printStackTrace();
            apiResponse = ApiResponse.error(ResultCode.ERROR, e.getMessage());
        }

        return apiResponse;
    }

    public ApiResponse removeQuestion(Integer id) {
        ApiResponse apiResponse = null;
        try {
            workQuestionDAO.deleteByPrimaryKey(id);
            apiResponse = ApiResponse.success("题目移除成功");
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<WorkQuDTO> addQuestion(WorkQuDTO workQuDTO) {
        ApiResponse<WorkQuDTO> apiResponse = null;
        try {
            List<Integer> qIdList = workQuDTO.getQuestionIdList();
            Admin admin=LoginContextUtil.getAdmin();
            if (qIdList.size() > 0) {
                for (Integer qId : qIdList) {
                    WorkQuestion workQu = new WorkQuestion();
                    workQu.setWorkId(workQuDTO.getWorkId());
                    workQu.setQuestionId(qId);
                    if(admin!=null)workQu.setCreator(admin.getId());
                    workQu.setCreateTime(new Date());
                    workQuestionDAO.insertSelective(workQu);
                }
            }
            apiResponse = ApiResponse.success(workQuDTO, "题目添加成功");
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<List<WorkVO>> findWorkByPageParams(WorkQueryDTO voParams) {
        ApiResponse apiResponse = null;
        Page page = PageHelper.startPage(voParams.getPageNo(), voParams.getPageSize());
        try {
            Map paramMap = org.apache.commons.beanutils.BeanUtils.describe(voParams);
            Admin admin = LoginContextUtil.getAdmin();
            if (voParams.getResourceScope() != null && voParams.getResourceScope() != 0) {
                if (admin != null) paramMap.put("creator", LoginContextUtil.getAdmin().getId());
            }
            List<Work> resultList = workDAO.selectByParam(paramMap);
            List<WorkVO> resultVOList = new ArrayList<WorkVO>();
            String includeQuestionInfo;
            for (Work w : resultList) {
                WorkVO wVo = new WorkVO.VOBuilder(w).build();
                includeQuestionInfo=QuestionTypeEnum.SINGLE_ELECTION.label+":"+workQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.SINGLE_ELECTION.value)+"、"+
                        QuestionTypeEnum.MULTIPLE_CHOICE.label+":"+workQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.MULTIPLE_CHOICE.value)+"、"+
                        QuestionTypeEnum.JUDGE_QUESTION.label+":"+workQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.JUDGE_QUESTION.value);
                wVo.setIncludeQuestionInfo(includeQuestionInfo);
                if (wVo.getModified() != null) {
                    admin = adminDAO.selectByPrimaryKey(wVo.getModified());
                    if (admin != null) {
                        wVo.setModifiedName(admin.getName());
                    } else {
                        wVo.setModifiedName("");
                    }
                }
                wVo.setObjectTypeText(CustomerTypeEnum.parseVal(w.getObjectType()).label);
                resultVOList.add(wVo);
            }

            PageInfo pageInfo = new PageInfo(page);
            pageInfo.setList(resultVOList);
            apiResponse = ApiResponse.success(resultVOList, (int) pageInfo.getTotal());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<List<QuestionVO>> findQuestionByPageParams(WorkQuQueryDTO dtoParams) {
        ApiResponse apiResponse = null;
        Page page = PageHelper.startPage(dtoParams.getPageNo(), dtoParams.getPageSize());
        try {
            Map paramMap = org.apache.commons.beanutils.BeanUtils.describe(dtoParams);
            List<QuestionVO> resultVOList = workQuestionDAO.selectByParam(paramMap);
            for (QuestionVO qVo : resultVOList) {
                qVo.setObjectTypeText(CustomerTypeEnum.parseVal(qVo.getObjectType()).label);
                qVo.setQuestionTypeText(QuestionTypeEnum.parseVal(qVo.getExamType()).label);
            }
            PageInfo pageInfo = new PageInfo(page);
            pageInfo.setList(resultVOList);
            apiResponse = ApiResponse.success(resultVOList, (int) pageInfo.getTotal());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<List<QuestionVO>> findAddQuestionByParam(WorkQuQueryDTO dtoParams) {
        ApiResponse apiResponse = null;
        Page page = PageHelper.startPage(dtoParams.getPageNo(), dtoParams.getPageSize());
        try {
            Map paramMap = org.apache.commons.beanutils.BeanUtils.describe(dtoParams);
            List<Question> resultList = workQuestionDAO.selectAddQuestionByParam(paramMap);
            List<QuestionVO> resultVOList = new ArrayList<QuestionVO>();
            for (Question q : resultList) {
                QuestionVO qVo = new QuestionVO();
                BeanUtils.copyProperties(q, qVo);
                qVo.setObjectTypeText(CustomerTypeEnum.parseVal(q.getObjectType()).label);
                qVo.setQuestionTypeText(QuestionTypeEnum.parseVal(qVo.getExamType()).label);
                resultVOList.add(qVo);
            }
            PageInfo pageInfo = new PageInfo(page);
            pageInfo.setList(resultVOList);
            apiResponse = ApiResponse.success(resultVOList, (int) pageInfo.getTotal());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<WorkVO> getWork(Integer workId) {
        ApiResponse apiResponse = null;
        try {

            Work w = workDAO.selectByPrimaryKey(workId);
            WorkVO wVo = new WorkVO.VOBuilder(w).build();
            String includeQuestionInfo=QuestionTypeEnum.SINGLE_ELECTION.label+":"+workQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.SINGLE_ELECTION.value)+"、"+
                    QuestionTypeEnum.MULTIPLE_CHOICE.label+":"+workQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.MULTIPLE_CHOICE.value)+"、"+
                    QuestionTypeEnum.JUDGE_QUESTION.label+":"+workQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.JUDGE_QUESTION.value);
            wVo.setIncludeQuestionInfo(includeQuestionInfo);
            wVo.setIncludeQuestionInfo(includeQuestionInfo);
            if (wVo.getModified() != null) {
                Admin admin = adminDAO.selectByPrimaryKey(wVo.getModified());
                if (admin != null) {
                    wVo.setModifiedName(admin.getName());
                }
            }
            apiResponse = ApiResponse.success(wVo);
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse deleteWork(Integer workId) {
        ApiResponse apiResponse = null;
        try {
            workQuestionDAO.deleteByWorkId(workId);
            workDAO.deleteByPrimaryKey(workId);
            apiResponse = ApiResponse.success("作业删除成功");
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<Set<IndexWorkVO>> selectWorkByParam(IndexQueryVO indexQueryVO) {
        List<IndexWorkVO> list = workDAO.selectWorkByParam(indexQueryVO);
        Student student = LoginContextUtil.getStudent();
        if (student == null) {
            return ApiResponse.error(ResultCode.INVALID_PARAM);
        }
        TreeSet<IndexWorkVO> set = new TreeSet<>();
        if (list != null && list.size() > 0) {
            for (IndexWorkVO indexWorkVO : list) {
                //查看发布范围
                List<WorkPublishRange> workPublishRangeList = workPublishRangeDAO.selectByCondition(indexWorkVO.getWorkPublishId(), student.getSchoolId(), student.getClassId());
                if (workPublishRangeList != null && workPublishRangeList.size() > 0) {
                    set.add(indexWorkVO);
                }
            }
        }
        return ApiResponse.success(set);
    }
}
